<template>
  <transition class="animated zoomIn">
    <div class="video-content" ref="videoContent" v-show="showVideo">
      <div class="avatar-wave-jieting" v-if="showJieting && othersInfo">
        <div class="ripple-wave">
          <div class="ripple-wave-2">
            <img class="avatar" :src="getImage(othersInfo.avatar)" />
          </div>
        </div>
        <div class="person-one">{{ othersInfo.name }}</div>
        <div class="person-one">{{ getType }}</div>
      </div>
      <!-- muted -->
      <video
        v-show="localStream"
        class="localvideo"
        ref="localvideo"
        autoplay
        playsinline
        muted
        :class="[
          { noneFilter: currentFilter == 1 },
          { blur: currentFilter == 2 },
          { grayscale: currentFilter == 3 },
          { invert: currentFilter == 4 },
          { sepia: currentFilter == 5 },
          { isFront: myVideoFront },
        ]"
        @click="changVideoLocation('local')"
        v-draggable="!myVideoFront"
      ></video>
      <video
        v-show="remoteStream"
        class="remotevideo"
        ref="remotevideo"
        autoplay
        playsinline
        :class="[
          { noneFilter: remoteFilter == 1 },
          { blur: remoteFilter == 2 },
          { grayscale: remoteFilter == 3 },
          { invert: remoteFilter == 4 },
          { sepia: remoteFilter == 5 },
          { isFront: !myVideoFront },
        ]"
        @click="changVideoLocation('remote')"
        v-draggable="myVideoFront"
      ></video>
      <div class="avatar-wave-top" v-if="othersInfo && showTouXiang">
        <div class="ripple-wave">
          <div class="ripple-wave-2">
            <img class="avatar" :src="getImage(othersInfo.avatar)" />
          </div>
        </div>
        <div class="person-one">{{ othersInfo.name }}</div>
      </div>
      <div class="filter-top" v-if="rtcType == 2">
        <select id="filter" @change="selectFilter($event)">
          <option
            v-for="(item, index) in filterList"
            :key="index"
            :value="item.id"
          >
            {{ item.name }}
          </option>
        </select>
      </div>
      <div class="canvas-top">
        <canvas ref="photo" v-show="1 == 2"></canvas>
      </div>
      <div class="tools" v-if="isShowTools">
        <div
          class="jinyan tools-icon"
          @click="stopLocalAudio"
          :class="{ jinyanzhong: isJinyan }"
          v-show="showJinyan"
        ></div>
        <div
          class="fanzhuan tools-icon"
          @click="changeCamera"
          v-show="!showJieting && !audioOnly"
        >
          摄像头
        </div>
        <div
          class="paizhao tools-icon"
          @click="snapshot"
          v-show="!showJieting && !audioOnly"
        >
          拍照
        </div>
        <div
          class="yangsheng tools-icon"
          @click="speakerAudio"
          :class="{ yangshengzhong: isYangsheng }"
          v-show="showYangsheng"
        ></div>
        <div
          class="audio_only tools-icon"
          @click="stopVideo"
          v-show="showStopVideo"
        ></div>
        <div
          class="jieting tools-icon"
          @click="jietingCall"
          v-show="showJieting"
        ></div>
        <div
          class="hang_up tools-icon"
          @click="guaduanCall"
          v-show="showGuaduan"
        ></div>
        <div
          class="refuse_call tools-icon"
          @click="jujueCall"
          v-show="showJujue"
        ></div>
      </div>

      <div class="messages" v-if="isShowMessage">
        <input type="text" v-model="localMessage" />
        <div class="bubbly-button message-btn" @click="transFormMessage">
          发送文字
        </div>
        <input
          type="text"
          v-model="remoteMessage"
          placeholder="接受到的文字信息"
          disabled
        />
      </div>
    </div>
  </transition>

  <transition>
    <div class="room">
      <div class="avatar-wave-top">
        <div class="ripple-wave">
          <div class="ripple-wave-2">
            <img class="avatar" :src="getImage(info.avatar)" />
          </div>
        </div>
        <div class="person-one">{{ info.name }}</div>
      </div>
      <div class="avatar-wave-bottom" v-if="othersInfo">
        <div class="ripple-wave">
          <div class="ripple-wave-2">
            <img class="avatar" :src="getImage(othersInfo.avatar)" />
          </div>
        </div>
        <div class="person-one">{{ othersInfo.name }}</div>
      </div>
      <div class="avatar-wave-button">
        <div v-if="full" style="color: #fff; font-size: 22px">
          房间人数已满..
        </div>
        <div
          v-if="!full"
          :class="['call', 'bubbly-button', othersInfo ? '' : 'disabled']"
          @click="makeCall($event, 'video')"
        >
          {{ othersInfo ? "视频聊天" : "等待视频聊天..." }}
        </div>
        <div
          v-if="!full"
          :class="['call', 'bubbly-button', othersInfo ? '' : 'disabled']"
          @click="makeCall($event, 'audio')"
        >
          {{ othersInfo ? "语音聊天" : "等待语音聊天..." }}
        </div>

        <div
          v-if="!full"
          :class="['call', 'bubbly-button', othersInfo ? '' : 'disabled']"
          @click="makeLink($event)"
        >
          {{ othersInfo ? "建立链接" : "等待建立链接..." }}
        </div>
      </div>
    </div>
  </transition>
</template>

<script>
import inobounce from "inobounce";
import { Toast } from "vant";
export default {
  name: "App",
  components: {},
  data() {
    return {
      myVideoFront: true,
      info: {
        //自己信息
        name: Date.now(),
        avatar: Math.ceil(Math.random() * 9) + ".jpg",
      },
      rtcType: "", //1.语音 2.视频 3.文字 4.文件
      localMessage: "", //本地文字
      remoteMessage: "", //远端文字
      sendChannel: null,
      receiveChannel: null,
      isShowMessage: false,
      isShowTools: true,
      isShowInput: true,
      othersInfo: "", //对方信息
      state: "init", //当前状态
      room: "vip", //房间名称
      isFront: true, //是否是前置摄像头
      audioOnly: false, //只有语音
      showVideo: false, // 显示视频
      showJieting: false, // 显示接听界面
      showJinyan: false, //显示禁言
      showGuaduan: false, // 显示挂断界面
      showStopVideo: false, //显示挂断视频界面
      showTouXiang: false, //显示头像
      showJujue: false, //显示拒绝
      showYangsheng: false, //显示扬声
      isJinyan: false, //是否禁言
      isYangsheng: false, //是否扬声
      remoteStream: null, // 本地视频流
      localStream: null, // 远端视频流
      full: false, // 房间满人标志位
      filterList: [
        { id: 1, name: "none" },
        { id: 2, name: "blur" },
        { id: 3, name: "grayscale" },
        { id: 4, name: "invert" },
        { id: 5, name: "sepia" },
      ],
      currentFilter: 1,
      remoteFilter: 1,
      pcConfig: {
        iceServers: [
          {
            urls: "turn:webrtc.mpcheshi.com:3478",
            credential: "mpwebrtcpasswd",
            username: "mpwebrtc",
          },
        ],
        // iceServers: [
        //   {
        //     urls: "turn:stun.ukerd.com:3478", // 免费直接可用的iceserver列表  https://gist.github.com/yetithefoot/7592580，也可以自建
        //     credential: "123456",
        //     username: "lvming",
        //   },
        // ],
      },
    };
  },
  computed: {
    getType() {
      // if (this.audioOnly) {
      //   return "语言聊天";
      // } else {
      //   return "视频聊天";
      // }
      if (this.rtcType == 1) {
        return "语言聊天";
      } else if (this.rtcType == 2) {
        return "视频聊天";
      } else if (this.rtcType == 3) {
        return "文字聊天";
      }
    },
  },
  watch: {
    // 人满后页面不可点击，置灰
    full(val) {
      if (val) {
        document.documentElement.classList.add("gray");
      } else {
        document.documentElement.classList.remove("gray");
      }
    },
  },
  created() {
    let u = navigator.userAgent;
    if (u.indexOf("iPhone") > -1) {
      inobounce.enable();
    }
  },

  mounted() {
    let url = window.location.origin;
    if (process.env.NODE_ENV == "development") {
      // url = "wss://collider.mpcheshi.com";
      url = "http://localhost:3003/";
    }
    // 初始化socket.io
    this.socket = io.connect(url, {
      path: "/rtcket",
    });

    this.socket.emit("join", {
      room: this.room,
      info: this.info,
    });

    this.localVideo = this.$refs.localvideo;
    this.remoteVideo = this.$refs.remotevideo;
    this.socketMessage();
    this.removeControls();
  },
  methods: {
    changVideoLocation(type) {
      if (type == "remote" && !this.myVideoFront) {
        this.isShowTools = !this.isShowTools;
      } else if (type == "remote" && this.myVideoFront) {
        this.myVideoFront = false;
      } else if (type == "local" && this.myVideoFront) {
        this.isShowTools = !this.isShowTools;
      } else if (type == "local" && !this.myVideoFront) {
        this.myVideoFront = true;
      }
    },
    selectFilter(event) {
      this.currentFilter = event.target.value;
      this.sendMessage(99, { remoteFilter: this.currentFilter });
    },
    removeControls() {
      let video = document.getElementsByTagName("video");
      video.controls = false;
    },
    getImage(name) {
      return new URL(`./assets/avatar/avatar${name}`, import.meta.url).href;
    },
    socketMessage() {
      this.socket.on("message", (room, id, data) => {
        // console.log("room===", room, "id=", id, "data=", data);
        if (data.type == 3) {
          //拨打电话
          this.audioOnly = data.data.isAudioOnly;
          this.showTouXiang = data.data.showTouXiang;
          this.getCall();
        } else if (data.type == 9) {
          //只挂断视频
          this.showStopVideo = data.data.showStopVideo;
          this.showTouXiang = data.data.showTouXiang;
          this.stopAllVideo();
        } else if (data.type == 7) {
          //挂断电话，取消拨打
          this.leave();
        } else if (data.type == 8) {
          //挂断电话，拒绝接听
          Toast("对方拒绝");
          this.leave();
        } else if (data.type == 4 || data.type == 5 || data.type == 6) {
          let callData = data.data;
          if (callData.hasOwnProperty("type") && callData.type === "offer") {
            this.createAnswer(callData);
          } else if (
            callData.hasOwnProperty("type") &&
            callData.type == "answer"
          ) {
            //拿到 answer 后，再次调用 setRemoteDescription 设置远端 answer 描述
            this.pc.setRemoteDescription(new RTCSessionDescription(callData));
            this.pc.ondatachannel = this.receiveChannelCallback;
          } else if (
            callData.hasOwnProperty("type") &&
            callData.type === "candidate"
          ) {
            console.log(callData, "callData");
            let candidate = new RTCIceCandidate({
              //receivedSDP
              sdpMLineIndex: callData.label,
              candidate: callData.candidate,
            });
            console.log(candidate, "candidate================================");
            this.pc.addIceCandidate(candidate);
          } else {
            console.log("the message is invalid!", callData);
          }
        } else if (data.type == 99) {
          //打开滤镜
          this.remoteFilter = data.data.remoteFilter;
        } else if (data.type == 101) {
          this.rtcType = 3;
          this.showVideo = true;
          this.showJieting = true;
          this.showGuaduan = true;
          this.showTouXiang = data.data.showTouXiang;
        }
      });
      // 加入房间成功后
      this.socket.on("joined", (data, id) => {
        // console.log("data====", data, "id=====", id);
        // 设置当前用户和对方用户信息
        for (let key in data) {
          if (data[key]) {
            if (key == id) {
              this.info = data[key].info; //自己的信息：名称,头像，房间号
            } else {
              this.othersInfo = data[key].info; //对方的信息：名称,头像，房间号
            }
          }
        }
      });
      // 当前用户离开房间
      this.socket.on("leaved", () => {});
      // 其他人进入房间
      this.socket.on("otherjoin", (data) => {
        this.othersInfo = data.info;
      });
      // 其他人离开房间
      this.socket.on("otherleave", () => {
        this.othersInfo = "";
        this.leave();
      });
      // 人满了
      this.socket.on("full", (roomid, rooms) => {
        this.renderFull(rooms);
      });
    },

    renderFull(rooms) {
      this.full = true;

      let count = 0;
      for (let key in rooms) {
        if (rooms[key] && rooms[key].info && count < 2) {
          if (count == 1) {
            this.othersInfo = rooms[key].info;
          } else {
            this.info = rooms[key].info;
          }
          count++;
        }
      }
    },
    sendMessage(type, data) {
      // console.log("发送的message", "type=", type, "data=", data);
      this.socket.emit("message", this.room, { type: type, data: data });
    },
    animateButton(e) {
      e.preventDefault;
      //reset animation
      e.target.classList.remove("animate");

      e.target.classList.add("animate");

      return new Promise((resolve) => {
        setTimeout(function () {
          e.target.classList.remove("animate");
          resolve();
        }, 900);
      });
    },

    // 拨打电话
    async makeCall(e, type) {
      if (type == "audio") {
        this.rtcType = 1;
        this.audioOnly = true;
        this.showStopVideo = false;
        this.showTouXiang = true;
      } else {
        this.rtcType = 2;
        this.audioOnly = false;
        this.showStopVideo = true;
        this.showTouXiang = false;
      }
      await this.animateButton(e);
      this.state = "call";
      this.showVideo = true;
      this.showGuaduan = true;
      this.showJinyan = true;
      this.showYangsheng = true;
      this.showJieting = false;
      this.showJujue = false;
      await this.initLocalStream();
      let data = {
        type: "calling",
        isAudioOnly: this.audioOnly,
      };
      this.sendMessage(3, data); //拨打电话
    },

    //建立链接
    async makeLink(e) {
      this.rtcType = 3;
      this.showTouXiang = true;
      this.state = "call";
      this.showVideo = true;
      this.audioOnly = true;
      this.showGuaduan = true;
      this.isShowMessage = true;
      await this.initLocalStream();
      await this.animateButton(e);
      let data = {
        type: "calling",
      };
      this.sendMessage(101, data); //建立链接
    },

    //发送数据
    async transFormMessage(e) {
      await this.animateButton(e);
      this.sendChannel.send(this.localMessage);
      setTimeout(() => {
        this.localMessage = "";
      }, 200);
      // console.log(this.dc, "this.dc");
    },

    initState() {
      this.isFront = true; //摄像头正面
      this.audioOnly = false; //只有语音
      this.showVideo = false; // 显示视频
      this.showJieting = false; // 显示接听界面
      this.showJinyan = false; //显示禁言
      this.showGuaduan = false; // 显示挂断界面
      this.showStopVideo = false; //显示挂断视频界面
      this.showTouXiang = false; //显示头像
      this.showJujue = false; //显示拒绝
      this.isJinyan = false; //是否禁言
      this.isYangsheng = false; //是否扬声
      this.remoteStream = null; // 本地视频流
      this.localStream = null; // 远端视频流
      this.full = false; // 房间满人标志位
      this.currentFilter = 1; //本地滤镜
      this.remoteFilter = 1; //远程滤镜
      this.myVideoFront = true; //本地视频在前面
      this.isShowTools = true; //显示工具栏
      this.isShowInput = true;
      this.localMessage = null;
      this.remoteMessage = null;
    },
    // 挂断电话
    guaduanCall() {
      this.leave();
      this.sendMessage(7, "init");
    },
    // 拒绝通话
    jujueCall() {
      this.leave();
      this.sendMessage(8, "refuse");
    },
    //静音
    stopLocalAudio() {
      this.isJinyan = !this.isJinyan;
      if (this.localStream && this.isJinyan) {
        this.localStream.getTracks().forEach((item) => {
          if (item.kind == "audio") {
            item.enabled = false;
          }
        });
        Toast("本地静音了");
      } else if (this.localStream && !this.isJinyan) {
        this.localStream.getTracks().forEach((item) => {
          if (item.kind == "audio") {
            item.enabled = true;
          }
        });
        Toast("本地有声音了");
      }
    },
    //拍照
    snapshot() {
      const canvas = this.$refs.photo;
      canvas.width = window.innerWidth;
      canvas.height = window.innerHeight;
      this.filterList.map((item) => {
        if (item.id == this.currentFilter) {
          console.log(item.name);
          canvas.className = item.name;
        }
      });

      canvas
        .getContext("2d")
        .drawImage(this.localVideo, 0, 0, canvas.width, canvas.height);
      let dom = document.createElement("a");
      dom.href = canvas.toDataURL("image/png");
      dom.download = new Date().getTime() + ".png";
      dom.click();
      dom.remove();
    },
    //反转摄像头
    async changeCamera() {
      this.isFront = !this.isFront;
      let constraints;
      constraints = {
        video:
          window.navigator.userAgent.indexOf("Chrome") > -1
            ? {
                width: { ideal: window.innerWidth },
                height: { ideal: window.innerHeight },
              }
            : { facingMode: this.isFront ? "user" : "environment" }, // 在移动端暂不支持width和height属性
        audio: {
          echoCancellation: true,
          noiseSuppression: true,
          autoGainControl: true,
        },
      };
      window.navigator.mediaDevices
        .getUserMedia(constraints)
        .then((stream) => {
          let videoTrack = stream.getVideoTracks()[0];
          let audioTrack = stream.getAudioTracks()[0];
          let sender = this.pc.getSenders().find(function (s) {
            return s.track.kind == videoTrack.kind;
          });
          let sender2 = this.pc.getSenders().find(function (s) {
            return s.track.kind == audioTrack.kind;
          });
          sender.replaceTrack(videoTrack);
          sender2.replaceTrack(audioTrack);
          this.localStream = stream;
          this.localVideo.srcObject = this.localStream;
        })
        .catch((err) => {
          console.error("你的设备不支持切换前后摄像头");
        });
    },
    //开关扬声
    speakerAudio() {
      this.isYangsheng = !this.isYangsheng;
      if (this.remoteStream && this.isYangsheng) {
        Toast("本地扬声了");
        this.gotMediaStream().then(this.gotDevices);
      } else if (this.remoteStream && !this.isYangsheng) {
        Toast("本地听筒了");
        this.gotMediaStream().then(this.gotDevices);
      }
    },
    //只挂断视频
    stopVideo() {
      console.log("挂断视频");
      this.localStream.getTracks().forEach((item) => {
        if (item.kind == "video") item.stop();
      });
      this.remoteStream.getTracks().forEach((item) => {
        if (item.kind == "video") item.stop();
      });
      this.showStopVideo = false;
      this.showTouXiang = true;
      let data = {
        type: "stopVideo",
        showStopVideo: this.showStopVideo,
        showTouXiang: this.showTouXiang,
      };
      this.sendMessage(9, data);
    },
    stopAllVideo() {
      this.localStream.getTracks().forEach((item) => {
        if (item.kind == "video") item.stop();
      });
      this.remoteStream.getTracks().forEach((item) => {
        if (item.kind == "video") item.stop();
      });
    },
    // 收到来电电话
    getCall() {
      this.showVideo = true;
      this.showJinyan = false;
      this.showGuaduan = false;
      this.showStopVideo = false;
      this.showTouXiang = false;
      this.showYangsheng = false;
      this.showJieting = true;
      this.showJujue = true;
    },
    // 接听来电，接收人接听
    async jietingCall() {
      if (this.rtcType == 3) {
        this.showGuaduan = true;
        this.showStopVideo = false;
        this.showJieting = false;
        this.audioOnly = true;
        this.showTouXiang = this.audioOnly;
        this.isShowMessage = true;
      } else {
        this.showStopVideo = !this.audioOnly;
        this.showTouXiang = this.audioOnly;
        this.showJieting = false;
        this.showJujue = false;
        this.showGuaduan = true;
        this.showJinyan = true;
        this.showYangsheng = true;
      }

      await this.initLocalStream();

      await this.call();
    },
    // 发起点对点通信
    async call() {
      const offerOptions = {
        offerToRecieveAudio: 1,
        offerToRecieveVideo: 1,
      };
      let desc = await this.pc.createOffer(offerOptions); //创建 offer 信息后，先调用 setLocalDescription 存储本地 offer 描述
      console.log(desc, "接收人createOffer======================");
      this.offerdesc = desc;
      this.pc.setLocalDescription(desc);
      this.sendMessage(4, desc); //createAnswer 接收人：收到 offer 后，先调用 setRemoteDescription 存储远端 offer 描述；然后又创建 answer 信息，同样需要调用 setLocalDescription 存储本地 answer 描述
    },
    // 初始化本地视频
    async initLocalStream() {
      if (this.rtcType == 3) {
        this.createPeerConnection();
      } else {
        if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
          console.error("the getUserMedia is not supported!");
          Toast("您的浏览器暂不支持getUserMedia，请使用Safari打开");
          return;
        } else {
          // alert(JSON.stringify(navigator.mediaDevices.getSupportedConstraints()));
          let constraints;
          if (this.audioOnly) {
            constraints = {
              video: false,
              audio: {
                echoCancellation: true,
                noiseSuppression: true,
                autoGainControl: true,
              },
            };
          } else {
            constraints = {
              video:
                window.navigator.userAgent.indexOf("Chrome") > -1
                  ? {
                      width: { ideal: window.innerWidth },
                      height: { ideal: window.innerHeight },
                    }
                  : { facingMode: this.isFront ? "user" : "environment" }, // 在移动端暂不支持width和height属性
              audio: {
                echoCancellation: true, //回声消除
                noiseSuppression: true, //降噪
                autoGainControl: true, //自动增益
              },
            };
          }
          let stream = null;
          try {
            stream = await navigator.mediaDevices.getUserMedia(constraints);
          } catch (e) {
            Toast(e);
          }
          this.localStream = this.getMediaStream(stream);

          this.localVideo.srcObject = this.localStream;

          this.bindTracks();
        }
      }
    },
    gotMediaStream() {
      return navigator.mediaDevices.enumerateDevices();
    },
    gotDevices(deviceInfos) {
      // console.log(this.remoteStream.getAudioTracks()[0], "改之前");
      if (this.isYangsheng) {
        this.remoteVideo.volume = 0.1;
        console.log(this.remoteVideo.volume, "isYangsheng");
      } else {
        this.remoteVideo.volume = 1;
        console.log(this.remoteVideo.volume, "Yangsheng");
      }
      let that = this;
      console.log(this.remoteStream.getAudioTracks()[0], "改之后");
    },
    getMediaStream(stream) {
      if (this.localStream) {
        stream.getAudioTracks().forEach((track) => {
          this.localStream.addTrack(track);
          stream.removeTrack(track);
        });
      } else {
        this.localStream = stream;
      }
      return this.localStream;
    },
    async createAnswer(callData) {
      //收到 offer 后，先调用 setRemoteDescription 存储远端 offer 描述；然后又创建 answer 信息，同样需要调用 setLocalDescription 存储本地 answer 描述
      this.pc.setRemoteDescription(new RTCSessionDescription(callData));
      this.pc.ondatachannel = this.receiveChannelCallback;
      let desc = await this.pc.createAnswer();
      this.pc.setLocalDescription(desc);
      this.sendMessage(5, desc); //   呼叫人：拿到 answer 后，再次调用 setRemoteDescription 设置远端 answer 描述
    },
    bindTracks() {
      console.log("bind tracks into RTCPeerConnection!");

      if (this.pc === null || this.pc === undefined) {
        //console.error('pc is null or undefined!');
        //return;
        this.createPeerConnection();
      }

      if (this.localStream === null || this.localStream === undefined) {
        console.error("localstream is null or undefined!");
        // this.closePc();
        return;
      }

      this.localStream.getTracks().forEach((track) => {
        this.pc.addTrack(track, this.localStream);
      });
    },

    createPeerConnection() {
      console.log("create RTCPeerConnection!");
      if (!this.pc) {
        this.pc = new RTCPeerConnection(this.pcConfig);
        // console.log(this.pc, "create new RTCPeerConnection iceSever");
        this.sendChannel = this.pc.createDataChannel("sendDataChannel");
        console.log("createPeerConnection");
        // console.log(this.dc, "dccc");

        // this.pc.oniceconnectionstatechange = (evt) => {
        //   console.log(
        //     "ICE connection state change: " + evt.target.iceConnectionState
        //   );
        // };
        this.pc.onicecandidate = (e) => {
          //器需要将更改后的描述信息传送给远端 RTCPeerConnection，以更新远端的备选源。
          console.log(
            e.candidate,
            "onicecandidate监听 A 的ICE候选信息 如果收集到，就添加给 B 连接状态"
          );
          if (e.candidate) {
            //监听 A 的ICE候选信息 如果收集到，就添加给 B 连接状态
            let data = {
              type: "candidate",
              label: e.candidate.sdpMLineIndex,
              id: e.candidate.sdpMid,
              candidate: e.candidate.candidate,
            };
            this.sendMessage(6, data); //addIceCandidate 添加ICE连接状态
          } else {
            console.log("this is the end candidate");
          }
        };

        this.sendChannel.onopen = this.onSendChannelStateChange;
        this.sendChannel.onclose = this.onSendChannelStateChange;

        this.pc.ontrack = this.getRemoteStream;
      } else {
        console.log("the pc have be created!");
      }
    },

    onSendChannelStateChange() {
      const readyState = this.sendChannel.readyState;
      console.log("Send channel state is: " + readyState);
      if (readyState === "open") {
        console.log("Send open");
      } else {
        console.log("Send close");
      }
    },

    receiveChannelCallback(event) {
      console.log("Receive Channel Callback");
      this.receiveChannel = event.channel;
      this.receiveChannel.onmessage = this.onReceiveMessageCallback;
      this.receiveChannel.onopen = this.onReceiveChannelStateChange;
      this.receiveChannel.onclose = this.onReceiveChannelStateChange;
    },

    onReceiveMessageCallback(event) {
      this.remoteMessage = event.data;
      console.log("Received Message", event.data);
    },

    onReceiveChannelStateChange() {
      const readyState = this.receiveChannel.readyState;
      console.log(`Receive channel state is: ${readyState}`);
    },

    getRemoteStream(e) {
      this.remoteStream = e.streams[0];
      this.remoteVideo.srcObject = this.remoteStream;
    },

    closePc() {
      if (this.pc) {
        this.offerdesc = null;
        this.pc.close();
        this.pc = null;
      }
    },
    leave() {
      this.closeLocalMedia();
      this.closePc();
      this.initState();
    },
    closeLocalMedia() {
      if (this.localStream && this.localStream.getTracks()) {
        this.localStream.getTracks().forEach((track) => {
          track.stop();
        });
      }
      this.localStream = null;
    },
  },
  beforeUnmount() {
    inobounce.disable();
  },
};
</script>
<style>
.noneFilter {
  -webkit-filter: none;
  filter: none;
}

.blur {
  -webkit-filter: blur(3px);
  filter: blur(3px);
}

.grayscale {
  -webkit-filter: grayscale(1);
  filter: grayscale(1);
}

.invert {
  -webkit-filter: invert(1);
  filter: invert(1);
}

.sepia {
  -webkit-filter: sepia(1);
  filter: sepia(1);
}
video::-webkit-media-controls-start-playback-button {
  display: none;
}
.video-content {
  width: 100%;
  height: 100%;
  background-color: rgb(33, 26, 37);
  position: absolute;
  z-index: 999;
  display: flex;
  justify-content: center;
}

.video-content.animated {
  animation-duration: 0.4s;
}

.messages {
  position: absolute;
  top: 400px;
  z-index: 10;
}
.message-btn {
  margin-top: 20px;
  display: block !important;
}

.tools {
  width: 70%;
  height: 70px;
  position: absolute;
  bottom: 40px;
  display: flex;
  justify-content: space-evenly;
  z-index: 10;
}

.tools-icon {
  width: 50px;
  height: 50px;
  background-size: 100% 100%;
  background-repeat: no-repeat;
}

/* .tools-icon:first-child {
      margin-right: 20px;
    } */

/* .tools-icon:last-child {
      margin-left: 20px;
    } */
.jinyan {
  background-image: url("./assets/jinyan.svg");
  border-radius: 50%;
  background-color: #3dd332;
}

.fanzhuan {
  border-radius: 50%;
  background-color: turquoise;
  display: flex;
  align-items: center;
  justify-content: center;
}
.paizhao {
  border-radius: 50%;
  background-color: coral;
  display: flex;
  align-items: center;
  justify-content: center;
}
.jinyanzhong {
  background-color: red;
}

.yangsheng {
  background-image: url("./assets/speaker.png");
  background-size: 100% 100%;
  border-radius: 50%;
  background-color: #fff;
}

.yangshengzhong {
  background-color: #3dd332;
}

.jieting {
  background-image: url("./assets/jieting.svg");
}

.hang_up {
  background-image: url("./assets/hang_up.svg");
}

.refuse_call {
  background-image: url("./assets/hang_up.svg");
  margin-left: 20px;
}

.audio_only {
  background-image: url("./assets/vedio.jpeg");
  background-color: #fff;
  border-radius: 50%;
}

.localvideo {
  position: absolute;
  width: 30%;
  height: 30%;
  object-fit: fill;
  z-index: 9;
}

.remotevideo {
  position: absolute;
  width: 30%;
  height: 30%;
  object-fit: fill;
  z-index: 9;
}
.isFront {
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 1 !important;
}

.avatar-wave-jieting {
  position: absolute;
  width: 200px;
  height: 200px;
  left: 50%;
  transform: translateX(-50%);
  top: 167px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.filter-top {
  position: absolute;
  top: 0;
  z-index: 10;
}
.canvas-top {
  position: absolute;
  bottom: 0;
  left: 0;
}
.avatar-wave-top {
  position: absolute;
  width: 200px;
  height: 200px;
  left: 50%;
  transform: translateX(-50%);
  top: 67px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.avatar-wave-bottom {
  position: absolute;
  width: 200px;
  height: 200px;
  left: 50%;
  transform: translateX(-50%);
  bottom: 67px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.avatar-wave-button {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}

.person-one {
  margin-top: 20px;
  color: #fff;
}

@keyframes pulse-animation {
  0% {
    opacity: 1;
    transform: scale(1);
  }

  20% {
    opacity: 1;
    transform: scale(1);
  }

  80% {
    opacity: 0;
  }

  100% {
    opacity: 0;
    transform: scale(1.5);
  }
}

.room {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  background-color: rgb(33, 26, 37);
  display: flex;
  justify-content: center;
  align-items: center;
}

.avatar {
  display: block;
  width: 89px;
  height: 89px;
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 99;
  border-radius: 50%;
  transform: translate(-50%, -50%);
}

.ripple-wave {
  position: relative;
  border-radius: 50%;
  z-index: 1;
  margin: 0 auto;
  width: 100px;
  height: 100px;
}

.avatar-wave-jieting .ripple-wave::before,
.avatar-wave-jieting .ripple-wave::after {
  background-color: #1aad19;
}

.ripple-wave::before,
.ripple-wave::after {
  content: "";
  display: block;
  position: absolute;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background-color: #fff;
  will-change: transform, opacity;
}

.ripple-wave::after {
  animation: pulse-animation 2s cubic-bezier(0.24, 0, 0.38, 1) infinite;
  transition: opacity 0.4s, transform 0.4s;
}

.ripple-wave .ripple-wave-2 {
  position: absolute;
  height: inherit;
  width: inherit;
}

.avatar-wave-jieting .ripple-wave .ripple-wave-2::before {
  background-color: #1aad19;
}

.ripple-wave .ripple-wave-2::before {
  content: "";
  display: block;
  height: inherit;
  width: inherit;
  border-radius: 50%;
  background-color: #fff;
  animation: pulse-animation 2s cubic-bezier(0.24, 0, 0.38, 1) infinite;
  animation-delay: 0.24s;
}

.bubbly-button {
  width: auto;
  padding-left: 5px;
  padding-right: 5px;
  height: 34px;
  text-align: center;
  line-height: 34px;
  margin-bottom: 20px;
}

.bubbly-button.disabled {
  background-color: #ccc;
  box-shadow: none;
}

.bubbly-button {
  display: inline-block;
  -webkit-appearance: none;
  appearance: none;
  background-color: #ff0081;
  color: #fff;
  border-radius: 4px;
  border: none;
  cursor: pointer;
  position: relative;
  transition: transform ease-in 0.1s, box-shadow ease-in 0.25s;
  box-shadow: 0 2px 25px rgba(255, 0, 130, 0.5);
}

.bubbly-button:focus {
  outline: 0;
}

.bubbly-button:before,
.bubbly-button:after {
  position: absolute;
  content: "";
  display: block;
  width: 140%;
  height: 100%;
  left: -20%;
  z-index: -1000;
  transition: all ease-in-out 0.5s;
  background-repeat: no-repeat;
}

.bubbly-button:before {
  display: none;
  top: -75%;
  background-image: radial-gradient(circle, #ff0081 20%, transparent 20%),
    radial-gradient(circle, transparent 20%, #ff0081 20%, transparent 30%),
    radial-gradient(circle, #ff0081 20%, transparent 20%),
    radial-gradient(circle, #ff0081 20%, transparent 20%),
    radial-gradient(circle, transparent 10%, #ff0081 15%, transparent 20%),
    radial-gradient(circle, #ff0081 20%, transparent 20%),
    radial-gradient(circle, #ff0081 20%, transparent 20%),
    radial-gradient(circle, #ff0081 20%, transparent 20%),
    radial-gradient(circle, #ff0081 20%, transparent 20%);
  background-size: 10% 10%, 20% 20%, 15% 15%, 20% 20%, 18% 18%, 10% 10%, 15% 15%,
    10% 10%, 18% 18%;
}

.bubbly-button:after {
  display: none;
  bottom: -75%;
  background-image: radial-gradient(circle, #ff0081 20%, transparent 20%),
    radial-gradient(circle, #ff0081 20%, transparent 20%),
    radial-gradient(circle, transparent 10%, #ff0081 15%, transparent 20%),
    radial-gradient(circle, #ff0081 20%, transparent 20%),
    radial-gradient(circle, #ff0081 20%, transparent 20%),
    radial-gradient(circle, #ff0081 20%, transparent 20%),
    radial-gradient(circle, #ff0081 20%, transparent 20%);
  background-size: 15% 15%, 20% 20%, 18% 18%, 20% 20%, 15% 15%, 10% 10%, 20% 20%;
}

.bubbly-button:active {
  transform: scale(0.9);
  background-color: #e60074;
  box-shadow: 0 2px 25px rgba(255, 0, 130, 0.2);
}

.bubbly-button.animate:before {
  display: block;
  animation: topBubbles ease-in-out 0.75s forwards;
}

.bubbly-button.animate:after {
  display: block;
  animation: bottomBubbles ease-in-out 0.75s forwards;
}

@keyframes topBubbles {
  0% {
    background-position: 5% 90%, 10% 90%, 10% 90%, 15% 90%, 25% 90%, 25% 90%,
      40% 90%, 55% 90%, 70% 90%;
  }

  50% {
    background-position: 0% 80%, 0% 20%, 10% 40%, 20% 0%, 30% 30%, 22% 50%,
      50% 50%, 65% 20%, 90% 30%;
  }

  100% {
    background-position: 0% 70%, 0% 10%, 10% 30%, 20% -10%, 30% 20%, 22% 40%,
      50% 40%, 65% 10%, 90% 20%;
    background-size: 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%;
  }
}

@keyframes bottomBubbles {
  0% {
    background-position: 10% -10%, 30% 10%, 55% -10%, 70% -10%, 85% -10%,
      70% -10%, 70% 0%;
  }

  50% {
    background-position: 0% 80%, 20% 80%, 45% 60%, 60% 100%, 75% 70%, 95% 60%,
      105% 0%;
  }

  100% {
    background-position: 0% 90%, 20% 90%, 45% 70%, 60% 110%, 75% 80%, 95% 70%,
      110% 10%;
    background-size: 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%;
  }
}
</style>
